from pml.Parser.public import *

class Variable(Node):
    def __init__(self, id=None, body=None, bp=None, ep=None, depth=0):
        super().__init__('variable', bp, ep, depth)
        self.id = id
        self.body = body
    def __repr__(self):
        return 'Variable({})(\n{}id={},\n{}body={}\n{})'.format(self.depth, '\t' * self.depth, self.id, '\t' * self.depth, self.body, '\t' * (self.depth - 1))

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        return self

    @staticmethod
    def tp_init(frame, this, position):
        pass

class Let(Node):
    def __init__(self, id=None, body=None, bp=None, ep=None, depth=0):
        super().__init__('let', bp, ep, depth)
        self.id = id
        self.body = body
    def __repr__(self):
        return 'Let({})(\n{}id={},\n{}body={}\n{})'.format(self.depth, '\t' * self.depth, self.id, '\t' * self.depth, self.body, '\t' * (self.depth - 1))

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        return self

    @staticmethod
    def tp_init(frame, this, position):
        pass

class Const(Node):
    def __init__(self, id=None, body=None, bp=None, ep=None, depth=0):
        super().__init__('const', bp, ep, depth)
        self.id = id
        self.body = body
    def __repr__(self):
        return 'Const({})(\n{}id={},\n{}body={}\n{})'.format(self.depth, '\t' * self.depth, self.id, '\t' * self.depth, self.body, '\t' * (self.depth - 1))

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        return self

    @staticmethod
    def tp_init(frame, this, position):
        pass

class VariableBuilder(ASTBuilder):
    def __init__(self, tokens=None, depth=0):
        super().__init__('Variable', tokens, depth)

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        self.methods['buildVariable'] = self.buildVariable

        return self

    @staticmethod
    def buildVariable(frame, this: 'VariableBuilder', position):
        bp = this.token.bp
        keyword = this.token.value
        this.getNextToken()
        bodyBuilder = Parser.Expression.ExpressionBuilder(this.tokens, depth=this.depth - 1)
        body = bodyBuilder.buildExpression(frame, bodyBuilder, position)
        if body.obj.expression.obj.op != TokenConstants.Keywords.IS:
            # error
            pass
        id = body.obj.expression.obj.left
        body = body.obj.expression.obj.right
        del bodyBuilder
        this.getLastToken()
        ep = this.token.ep
        try:
            this.getNextToken()
        except StopIteration:
            pass
        if keyword == TokenConstants.Keywords.VAR:
            return Objects.object.PMTypeObject(Variable(id, body, bp, ep, depth=this.depth).getObject())
        elif keyword == TokenConstants.Keywords.LET:
            return Objects.object.PMTypeObject(Let(id, body, bp, ep, depth=this.depth).getObject())
        else:
            return Objects.object.PMTypeObject(Const(id, body, bp, ep, depth=this.depth).getObject())

    @staticmethod
    def tp_init(frame, this: 'VariableBuilder', position):
        pass
